home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ptoc / part09 < prev    next >
Encoding:
Internet Message Format  |  1987-07-27  |  53.3 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i073:  Pascal to C translator, Part09/12
  5. Message-ID: <724@uunet.UU.NET>
  6. Date: 28 Jul 87 19:36:15 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2548
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
  12. Posting-number: Volume 10, Issue 73
  13. Archive-name: ptoc/Part09
  14.  
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 9 (of 12)."
  23. # Contents:  ptc.p.3
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'ptc.p.3' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'ptc.p.3'\"
  27. else
  28. echo shar: Extracting \"'ptc.p.3'\" \(50280 characters\)
  29. sed "s/^X//" >'ptc.p.3' <<'END_OF_FILE'
  30. X                    tx^.tto := ty^.thi
  31. X                    end
  32. X                else if ty^.tt = nscalar then
  33. X                    begin
  34. X                    ty := ty^.tscalid;
  35. X                    tx^.tfrom := ty;
  36. X                    while ty^.tnext <> nil do
  37. X                        ty := ty^.tnext;
  38. X                    tx^.tto := ty
  39. X                    end
  40. X                else if ty = typnods[tchar] then
  41. X                    begin
  42. X                    currsym.st := schar;
  43. X                    currsym.vchr := chr(minchar);
  44. X                    tx^.tfrom := mklit;
  45. X                    currsym.st := schar;
  46. X                    currsym.vchr := chr(maxchar);
  47. X                    tx^.tto := mklit
  48. X                    end
  49. X                else if ty = typnods[tinteger] then
  50. X                    begin
  51. X                    currsym.st := sinteger;
  52. X                    currsym.vint := -maxint;
  53. X                    tx^.tfrom := mklit;
  54. X                    currsym.st := sinteger;
  55. X                    currsym.vint := maxint;
  56. X                    tx^.tto := mklit
  57. X                    end
  58. X                else
  59. X                    fatal(etree);
  60. X                tx^.tforstmt := tz;
  61. X                tx^.tincr := true
  62. X                end;
  63. X              npredef,
  64. X              nfileof:
  65. X                if opn then
  66. X                    begin
  67. X                    (* create file-struct initialization *)
  68. X                    ty := mknode(nselect);
  69. X                    ty^.trecord := ti;
  70. X                    ty^.tfield :=
  71. X                        oldid(defnams[dzinit]^.lid,
  72. X                                lforward);
  73. X                    tx := mknode(nassign);
  74. X                    tx^.tlhs := ty;
  75. X                    currsym.st := sinteger;
  76. X                    currsym.vint := 0;
  77. X                    tx^.trhs := mklit
  78. X                    end
  79. X                else begin
  80. X                    (* create file-struct wrapup *)
  81. X                    tx := mknode(ncall);
  82. X                    tx^.tcall := 
  83. X                        oldid(defnams[dclose]^.lid,
  84. X                                lidentifier);
  85. X                    tx^.taparm := ti
  86. X                     end;
  87. X              nrecord:
  88. X                begin
  89. X                ty := nil;
  90. X                tq := tq^.tflist;
  91. X                while tq <> nil do
  92. X                    begin
  93. X                    if filevar(typeof(tq^.tbind)) then
  94. X                        begin
  95. X                        tz := tq^.tidl;
  96. X                        while tz <> nil do
  97. X                            begin
  98. X                            tx := mknode(nselect);
  99. X                            tx^.trecord := ti;
  100. X                            tx^.tfield := tz;
  101. X                            tx := fileinit(tx,
  102. X                                typeof(tq^.tbind),
  103. X                                opn);
  104. X                            tx^.tnext := ty;
  105. X                            ty := tx;
  106. X                            tz := tz^.tnext
  107. X                            end
  108. X                        end;
  109. X                    tq := tq^.tnext
  110. X                    end;
  111. X                tx := mknode(nbegin);
  112. X                tx^.tbegin := ty
  113. X                end;
  114. X            end;(* case *)
  115. X            fileinit := tx
  116. X        end;
  117. X
  118. X    begin    (* initcode *)
  119. X        while tp <> nil do
  120. X            begin
  121. X            initcode(tp^.tsubsub);
  122. X            tv := tp^.tsubvar;
  123. X            while tv <> nil do
  124. X                begin
  125. X                tq := typeof(tv^.tbind);
  126. X                if filevar(tq) then
  127. X                    begin
  128. X                    ti := tv^.tidl;
  129. X                    while ti <> nil do
  130. X                        begin
  131. X                        tu := fileinit(ti, tq, true);
  132. X                        linkup(tp, tu);
  133. X                        tu^.tnext := tp^.tsubstmt;
  134. X                        tp^.tsubstmt := tu;
  135. X                        while tu^.tnext <> nil do
  136. X                            tu := tu^.tnext;
  137. X                        tu^.tnext := fileinit(ti, tq,
  138. X                                    false);
  139. X                        linkup(tp, tu^.tnext);
  140. X                        ti := ti^.tnext
  141. X                        end
  142. X                    end;
  143. X                tv := tv^.tnext;
  144. X                end;
  145. X            tp := tp^.tnext
  146. X            end
  147. X    end;    (* initcode *)
  148. X
  149. Xbegin    (* transform *)
  150. X    renamc;
  151. X    renamp(top^.tsubsub, false);
  152. X    extract(top);
  153. X    renamf(top);
  154. X    initcode(top^.tsubsub);
  155. X    global(top, top, false)
  156. Xend;    (* transform *)
  157. X
  158. X(*    Emit C-code for program or module.                *)
  159. Xprocedure emit;
  160. X
  161. Xconst    include    = '# include ';
  162. X    define    = '# define ';
  163. X    ifdef    = '# ifdef ';
  164. X    ifndef    = '# ifndef ';
  165. X    elsif    = '# else';
  166. X    endif    = '# endif';
  167. X    static    = 'static ';
  168. X    xtern    = 'extern ';
  169. X    typdef    = 'typedef ';
  170. X    registr    = 'register ';
  171. X    usigned    = 'unsigned ';
  172. X    indstep    = 8;
  173. X
  174. Xvar    conflag,
  175. X    setused,
  176. X    dropset,
  177. X    donearr    : boolean;
  178. X    doarrow,
  179. X    indnt    : integer;
  180. X
  181. X    procedure increment;
  182. X    begin
  183. X        indnt := indnt + indstep
  184. X    end;
  185. X
  186. X    procedure decrement;
  187. X    begin
  188. X        indnt := indnt - indstep
  189. X    end;
  190. X
  191. X    (*    Write tabs/blanks to properly (?) indent C-code.    *) 
  192. X    procedure indent;
  193. X
  194. X    var    i    : integer;
  195. X
  196. X    begin
  197. X        i := indnt;
  198. X        (* limit indent to an integral number of tabs *)
  199. X        if i > 60 then
  200. X            i := i div tabwidth * tabwidth;
  201. X        while i >= tabwidth do
  202. X            begin
  203. X            write(tab1);
  204. X            i := i - tabwidth
  205. X            end;
  206. X        while i > 0 do
  207. X            begin
  208. X            write(space);
  209. X            i := i - 1
  210. X            end;
  211. X    end;
  212. X
  213. X    (*    Determine if tp must be cast to an integer before being    *)
  214. X    (*    used in an arithmetic expression.            *)
  215. X    function arithexpr(tp : treeptr) : boolean;
  216. X
  217. X    begin
  218. X        tp := typeof(tp);
  219. X        if tp^.tt = nsubrange then
  220. X            if tp^.tup^.tt = nconfarr then
  221. X                tp := typeof(tp^.tup^.tindtyp)
  222. X            else
  223. X                tp := typeof(tp^.tlo);
  224. X        arithexpr := (tp = typnods[tinteger]) or
  225. X                (tp = typnods[tchar]) or
  226. X                    (tp = typnods[treal])
  227. X    end;
  228. X
  229. X    procedure eexpr(tp : treeptr);                forward;
  230. X    procedure etypedef(tp : treeptr);            forward;
  231. X
  232. X    (*    Emit code to select a record member.    *)
  233. X    procedure eselect(tp : treeptr);
  234. X
  235. X    begin
  236. X        doarrow := doarrow + 1;
  237. X        eexpr(tp);
  238. X        doarrow := doarrow - 1;
  239. X        if donearr then
  240. X            donearr := false
  241. X        else
  242. X            write('.')
  243. X    end;
  244. X
  245. X    (*    Emit code for call to a predefined function/procedure.    *)
  246. X    procedure epredef(ts, tp : treeptr);
  247. X
  248. X    label    444, 555;
  249. X
  250. X    var    tq,
  251. X        tv, tx    : treeptr;
  252. X        td    : predefs;
  253. X        nelems    : integer;
  254. X        ch    : char;
  255. X        txtfile    : boolean;
  256. X
  257. X        (*    Determine a format-code for fprintf.        *)
  258. X        (*    Update nelems as a sideeffect.            *)
  259. X        function typeletter(tp : treeptr) : char;
  260. X
  261. X        label    999;
  262. X
  263. X        var    tq    : treeptr;
  264. X
  265. X        begin
  266. X            tq := tp;
  267. X            if tq^.tt = nformat then
  268. X                begin
  269. X                if tq^.texpl^.tt = nformat then
  270. X                    begin
  271. X                    typeletter := 'f';
  272. X                    goto 999
  273. X                    end;
  274. X                tq := tp^.texpl
  275. X                end;
  276. X            tq := typeof(tq);
  277. X            if tq^.tt = nsubrange then
  278. X                tq := typeof(tq^.tlo);
  279. X            if tq = typnods[tstring] then
  280. X                typeletter := 's'
  281. X            else if tq = typnods[tinteger] then
  282. X                typeletter := 'd'
  283. X            else if tq = typnods[tchar] then
  284. X                typeletter := 'c'
  285. X            else if tq = typnods[treal] then
  286. X                if tp^.tt = nformat then
  287. X                    typeletter := 'e'
  288. X                else
  289. X                    typeletter := 'g'
  290. X            else if tq = typnods[tboolean] then
  291. X                begin
  292. X                typeletter := 'b';
  293. X                nelems := 6
  294. X                end
  295. X            else if tq^.tt = narray then
  296. X                begin
  297. X                typeletter := 'a';
  298. X                nelems := crange(tq^.taindx)
  299. X                end
  300. X            else if tq^.tt = nconfarr then
  301. X                begin
  302. X                typeletter := 'v';
  303. X                nelems := 0
  304. X                end
  305. X            else
  306. X                fatal(etree);
  307. X        999:
  308. X        end;    (* typeletter *)
  309. X
  310. X        procedure etxt(tp : treeptr);
  311. X
  312. X        var    w    : toknbuf;
  313. X            c    : char;
  314. X            i    : toknidx;
  315. X
  316. X        begin
  317. X            case tp^.tt of
  318. X              nid:
  319. X                begin
  320. X                tp := idup(tp);
  321. X                if tp^.tt = nconst then
  322. X                    etxt(tp^.tbind)
  323. X                else
  324. X                    fatal(etree)
  325. X                end;
  326. X              nstring:
  327. X                begin
  328. X                (* printf format string *)
  329. X                gettokn(tp^.tsym^.lstr, w);
  330. X                i := 1;
  331. X                while w[i] <> chr(null) do
  332. X                    begin
  333. X                    c := w[i];
  334. X                    if (c = cite) or (c = bslash) then
  335. X                        write(bslash)
  336. X                    else if c = percent then
  337. X                        write(percent);
  338. X                    write(c);
  339. X                    i := i + 1
  340. X                    end
  341. X                end;
  342. X              nchar:
  343. X                begin
  344. X                (* single character in printf format *)
  345. X                c := tp^.tsym^.lchar;
  346. X                if (c = cite) or (c = bslash) then
  347. X                    write(bslash)
  348. X                else if c = percent then
  349. X                    write(percent);
  350. X                write(c)
  351. X                end;
  352. X            end;(* case *)
  353. X        end;    (* etxt *)
  354. X
  355. X        (*    Emit format for fprintf.            *)
  356. X        procedure eformat(tq : treeptr);
  357. X
  358. X        var    tx    : treeptr;
  359. X            i    : integer;
  360. X
  361. X        begin
  362. X            case typeletter(tq) of
  363. X              'a':
  364. X                begin
  365. X                write(percent);
  366. X                if tq^.tt = nformat then
  367. X                    if tq^.texpr^.tt = ninteger then
  368. X                        eexpr(tq^.texpr)
  369. X                    else
  370. X                        write('*');
  371. X                write('.', nelems:1, 's')
  372. X                end;
  373. X              'b':
  374. X                begin
  375. X                write(percent);
  376. X                if tq^.tt = nformat then
  377. X                    begin
  378. X                    if tq^.texpr^.tt = ninteger then
  379. X                        eexpr(tq^.texpr)
  380. X                    else
  381. X                        write('*')
  382. X                    end;
  383. X                write('s')
  384. X                end;
  385. X              'c':
  386. X                if tq^.tt = nchar then
  387. X                    etxt(tq)
  388. X                else begin
  389. X                    write(percent);
  390. X                    if tq^.tt = nformat then
  391. X                        if tq^.texpr^.tt = ninteger then
  392. X                            eexpr(tq^.texpr)
  393. X                        else
  394. X                            write('*');
  395. X                    write('c')
  396. X                     end;
  397. X              'd':
  398. X                begin
  399. X                write(percent);
  400. X                if tq^.tt = nformat then
  401. X                    begin
  402. X                    if tq^.texpr^.tt = ninteger then
  403. X                        eexpr(tq^.texpr)
  404. X                    else
  405. X                        write('*')
  406. X                    end
  407. X                else
  408. X                    write(intlen:1);
  409. X                write('d')
  410. X                end;
  411. X              'e':
  412. X                begin
  413. X                write(percent, space);
  414. X                tx := tq^.texpr;
  415. X                if tx^.tt = ninteger then
  416. X                    begin
  417. X                    i := cvalof(tx);
  418. X                    write(i:1, '.');
  419. X                    i := i - 7;
  420. X                    if i < 1 then
  421. X                        write('1')
  422. X                    else
  423. X                        write(i:1)
  424. X                    end
  425. X                else
  426. X                    write('*.*');
  427. X                write('e')
  428. X                end;
  429. X              'f':
  430. X                begin
  431. X                write(percent);
  432. X                tx := tq^.texpl;
  433. X                if tx^.texpr^.tt = ninteger then
  434. X                    begin
  435. X                    eexpr(tx^.texpr);
  436. X                    write('.');
  437. X                    tx := tq^.texpr;
  438. X                    if tx^.tt = ninteger then
  439. X                        begin
  440. X                        i := cvalof(tx);
  441. X                        tx := tq^.texpl^.texpr;
  442. X                        if i > cvalof(tx) - 1 then
  443. X                            write('1')
  444. X                        else
  445. X                            write(i:1)
  446. X                        end
  447. X                    else
  448. X                        write('*');
  449. X                    end
  450. X                else
  451. X                    write('*.*');
  452. X                write('f')
  453. X                end;
  454. X              'g':
  455. X                write(percent, fixlen:1, 'e');
  456. X              's':
  457. X                if tq^.tt = nstring then
  458. X                    etxt(tq)
  459. X                else begin
  460. X                    write(percent);
  461. X                    if tq^.tt = nformat then
  462. X                        if tq^.texpr^.tt = ninteger then
  463. X                            eexpr(tq^.texpr)
  464. X                        else
  465. X                            write('*.*');
  466. X                    write('s')
  467. X                     end
  468. X            end (* case *)
  469. X        end;    (* eformat *)
  470. X
  471. X        (*    Emit parameters to fprintf except format.    *)
  472. X        procedure ewrite(tq : treeptr);
  473. X
  474. X        var    tx    : treeptr;
  475. X
  476. X        begin
  477. X            case typeletter(tq) of
  478. X              'a':
  479. X                begin
  480. X                write(', ');
  481. X                tx := tq;
  482. X                if tq^.tt = nformat then
  483. X                    begin
  484. X                    if tq^.texpr^.tt <> ninteger then
  485. X                        begin
  486. X                          eexpr(tq^.texpr);
  487. X                          write(', ')
  488. X                        end;
  489. X                    tx := tq^.texpl
  490. X                    end;
  491. X                eexpr(tx);
  492. X                write('.A')
  493. X                end;
  494. X              'b':
  495. X                begin
  496. X                write(', ');
  497. X                tx := tq;
  498. X                if tq^.tt = nformat then
  499. X                    begin
  500. X                    if tq^.texpr^.tt <> ninteger then
  501. X                        begin
  502. X                          eexpr(tq^.texpr);
  503. X                          write(', ')
  504. X                        end;
  505. X                    tx := tq^.texpl
  506. X                    end;
  507. X                usebool := true;
  508. X                write('Bools[(int)(');
  509. X                eexpr(tx);
  510. X                write(')]')
  511. X                end;
  512. X              'c':
  513. X                begin
  514. X                if tq^.tt = nformat then
  515. X                    begin
  516. X                    if tq^.texpr^.tt <> ninteger then
  517. X                        begin
  518. X                        write(', ');
  519. X                        eexpr(tq^.texpr)
  520. X                        end;
  521. X                    write(', ');
  522. X                    eexpr(tq^.texpl)
  523. X                    end
  524. X                else if tq^.tt <> nchar then
  525. X                    begin
  526. X                    write(', ');
  527. X                    eexpr(tq)
  528. X                    end
  529. X                end;
  530. X              'd':
  531. X                begin
  532. X                write(', ');
  533. X                tx := tq;
  534. X                if tq^.tt = nformat then
  535. X                    begin
  536. X                    if tq^.texpr^.tt <> ninteger then
  537. X                        begin
  538. X                        eexpr(tq^.texpr);
  539. X                        write(', ')
  540. X                        end;
  541. X                    tx := tq^.texpl
  542. X                    end;
  543. X                eexpr(tx)
  544. X                end;
  545. X              'e':
  546. X                begin
  547. X                write(', ');
  548. X                tx := tq^.texpr;
  549. X                if tx^.tt <> ninteger then
  550. X                    begin
  551. X                    usemax := true;
  552. X                    eexpr(tx);
  553. X                    write(', Max(');
  554. X                    eexpr(tx);
  555. X                    write(' - 7, 1), ')
  556. X                    end;
  557. X                eexpr(tq^.texpl)
  558. X                end;
  559. X              'f':
  560. X                begin
  561. X                write(', ');
  562. X                tx := tq^.texpl;
  563. X                if tx^.texpr^.tt <> ninteger then
  564. X                    begin
  565. X                    eexpr(tx^.texpr);
  566. X                    write(', ')
  567. X                    end;
  568. X                if (tx^.texpr^.tt <> ninteger) or
  569. X                    (tq^.texpr^.tt <> ninteger) then
  570. X                    begin
  571. X                    usemax := true;
  572. X                    write('Max((');
  573. X                    eexpr(tx^.texpr);
  574. X                    write(') - (');
  575. X                    eexpr(tq^.texpr);
  576. X                    write(') - 1, 1), ')
  577. X                    end;
  578. X                eexpr(tq^.texpl^.texpl)
  579. X                end;
  580. X              'g':
  581. X                begin
  582. X                write(', ');
  583. X                eexpr(tq)
  584. X                end;
  585. X              's':
  586. X                begin
  587. X                if tq^.tt = nformat then
  588. X                    begin
  589. X                    if tq^.texpr^.tt <> ninteger then
  590. X                       begin
  591. X                        write(', ');
  592. X                        eexpr(tq^.texpr);
  593. X                        write(', ');
  594. X                        eexpr(tq^.texpr)
  595. X                       end;
  596. X                    write(', ');
  597. X                    eexpr(tq^.texpl)
  598. X                    end
  599. X                else if tq^.tt <> nstring then
  600. X                    begin
  601. X                    write(', ');
  602. X                    eexpr(tq)
  603. X                    end
  604. X                end
  605. X            end (* case *)
  606. X        end;    (* ewrite *)
  607. X
  608. X        (*    Emit size of *tp for call to malloc. CPU    *)
  609. X        (*    There is no safe way to compute the size of a    *)
  610. X        (*    particular variant of a C-union, we assume that    *)
  611. X        (*    the size can be computed by taking the address    *)
  612. X        (*    of the first member and subracting the address    *)
  613. X        (*    of the record and then adding the size of the    *)
  614. X        (*    variant containing the record.            *)
  615. X        procedure enewsize(tp : treeptr);
  616. X
  617. X        label    555;
  618. X
  619. X        var    tq, tx, ty    : treeptr;
  620. X            v        : integer;
  621. X
  622. X            (*    Emit size of union member tq.        *)
  623. X            procedure esubsize(tp, tq : treeptr);
  624. X
  625. X            label    555, 666;
  626. X
  627. X            var    tx, ty    : treeptr;
  628. X                addsize    : boolean;
  629. X
  630. X            begin
  631. X                tx := tq^.tvrnt;
  632. X                ty := tx^.tflist;
  633. X                if ty = nil then
  634. X                    begin
  635. X                    ty := tx^.tvlist;
  636. X                    while ty <> nil do
  637. X                        begin
  638. X                        if ty^.tvrnt^.tflist <> nil then
  639. X                            begin
  640. X                            ty := ty^.tvrnt^.tflist;
  641. X                            goto 555
  642. X                            end;
  643. X                        ty := ty^.tnext
  644. X                        end;
  645. X                555:
  646. X                    end;
  647. X                addsize := true;
  648. X                if ty = nil then
  649. X                    begin
  650. X                    (* empty variant, try using another *)
  651. X                    addsize := false;
  652. X                    ty := tx^.tup^.tup^.tvlist;
  653. X                    while ty <> nil do
  654. X                        begin
  655. X                        if ty^.tvrnt^.tflist <> nil then
  656. X                            begin
  657. X                            ty := ty^.tvrnt^.tflist;
  658. X                            goto 666
  659. X                            end;
  660. X                        ty := ty^.tnext
  661. X                        end;
  662. X                666:
  663. X                    end;
  664. X                if ty = nil then
  665. X                    begin
  666. X                    (* its getting too complicated,
  667. X                        ignore tag value *)
  668. X                    write('sizeof(*');
  669. X                    eexpr(tp);
  670. X                    write(')')
  671. X                    end
  672. X                else begin
  673. X                    (* compute offset to first member of
  674. X                       the selected union variant *)
  675. X                    write('Unionoffs(');
  676. X                    eexpr(tp);
  677. X                    write(', ');
  678. X                    printid(ty^.tidl^.tsym^.lid);
  679. X                    if addsize then
  680. X                        begin
  681. X                        (* add the size of the selected
  682. X                           union variant *)
  683. X                        write(') + sizeof(');
  684. X                        eexpr(tp);
  685. X                        write('->');
  686. X                        printid(tx^.tuid)
  687. X                        end;
  688. X                    write(')')
  689. X                     end
  690. X            end;
  691. X
  692. X        begin    (* newsize *)
  693. X            if (tp^.tnext <> nil) and unionnew then
  694. X                begin
  695. X                (* tnext points to a tag-value, evaluate it *)
  696. X                v := cvalof(tp^.tnext);
  697. X                (* find union type *)
  698. X                tq := typeof(tp);
  699. X                tq := typeof(tq^.tptrid);
  700. X                if tq^.tt <> nrecord then
  701. X                    fatal(etree);
  702. X                (* find corresponding variant *)
  703. X                tx := tq^.tvlist;
  704. X                while tx <> nil do
  705. X                    begin
  706. X                    ty := tx^.tselct;
  707. X                    while ty <> nil do
  708. X                        begin
  709. X                        if v = cvalof(ty) then
  710. X                            goto 555;
  711. X                        ty := ty^.tnext
  712. X                        end;
  713. X                    tx := tx^.tnext
  714. X                    end;
  715. X                fatal(etag);
  716. X            555:
  717. X                (* emit size for that variant *)
  718. X                esubsize(tp, tx)
  719. X                end
  720. X            else begin
  721. X                write('sizeof(*');
  722. X                eexpr(tp);
  723. X                write(')')
  724. X                 end
  725. X        end;    (* newsize *)
  726. X
  727. X    begin    (* epredef *)
  728. X        td := ts^.tsubstmt^.tdef;
  729. X        case td of
  730. X          dabs:
  731. X            begin
  732. X            tq := typeof(tp^.taparm);
  733. X            if (tq = typnods[tinteger]) or (tq^.tt = nsubrange) then
  734. X                write('abs(')            (* LIB *)
  735. X            else
  736. X                write('fabs(');            (* LIB *)
  737. X            eexpr(tp^.taparm);
  738. X            write(')')
  739. X            end;
  740. X          dargv:
  741. X            begin
  742. X            write('Argvgt(');
  743. X            eexpr(tp^.taparm);
  744. X            write(', ');
  745. X            eexpr(tp^.taparm^.tnext);
  746. X            write('.A, sizeof(');
  747. X            eexpr(tp^.taparm^.tnext);
  748. X            writeln('.A));')
  749. X            end;
  750. X          dchr:
  751. X            begin
  752. X            tq := typeof(tp^.taparm);
  753. X            if tq^.tt = nsubrange then
  754. X                if tq^.tup^.tt = nconfarr then
  755. X                    tq := typeof(tq^.tup^.tindtyp)
  756. X                else
  757. X                    tq := typeof(tq^.tlo);
  758. X            if (tq = typnods[tinteger]) or
  759. X                        (tq = typnods[tchar]) then
  760. X                eexpr(tp^.taparm)
  761. X            else begin
  762. X                write('(char)(');
  763. X                eexpr(tp^.taparm);
  764. X                write(')')
  765. X                 end
  766. X            end;
  767. X          ddispose:
  768. X            begin
  769. X            write('free(');                (* LIB *)
  770. X            eexpr(tp^.taparm);
  771. X            writeln(');')
  772. X            end;
  773. X          deof:
  774. X            begin
  775. X            write('Eof(');
  776. X            if tp^.taparm = nil then
  777. X                begin
  778. X                defnams[dinput]^.lused := true;
  779. X                printid(defnams[dinput]^.lid)
  780. X                end
  781. X            else
  782. X                eexpr(tp^.taparm);
  783. X            write(')')
  784. X            end;
  785. X          deoln:
  786. X            begin
  787. X            write('Eoln(');
  788. X            if tp^.taparm = nil then
  789. X                begin
  790. X                defnams[dinput]^.lused := true;
  791. X                printid(defnams[dinput]^.lid)
  792. X                end
  793. X            else
  794. X                eexpr(tp^.taparm);
  795. X            write(')');
  796. X            end;
  797. X          dexit:
  798. X            begin
  799. X            write('exit(');                (* OS *)
  800. X            if tp^.taparm = nil then
  801. X                write('0')
  802. X            else
  803. X                eexpr(tp^.taparm);
  804. X            writeln(');');
  805. X            end;
  806. X          dflush:
  807. X            begin
  808. X            write('fflush(');            (* LIB *)
  809. X            if tp^.taparm = nil then
  810. X                begin
  811. X                defnams[doutput]^.lused := true;
  812. X                printid(defnams[doutput]^.lid)
  813. X                end
  814. X            else
  815. X                eexpr(tp^.taparm);
  816. X            writeln('.fp);')
  817. X            end;
  818. X          dpage:
  819. X            begin
  820. X            (* write form-feed character *)
  821. X            write('Putchr(', ffchr, ', '); (* CHAR *)
  822. X            if tp^.taparm = nil then
  823. X                begin
  824. X                defnams[doutput]^.lused := true;
  825. X                printid(defnams[doutput]^.lid)
  826. X                end
  827. X            else
  828. X                eexpr(tp^.taparm);
  829. X            writeln(');');
  830. X            end;
  831. X          dput,
  832. X          dget:
  833. X            begin
  834. X            if typeof(tp^.taparm) = typnods[ttext] then
  835. X                if td = dget then
  836. X                    write('Getx')
  837. X                else
  838. X                    write('Putx')
  839. X            else begin
  840. X                write(voidcast);
  841. X                if td = dget then
  842. X                    write('Get')
  843. X                else
  844. X                    write('Put')
  845. X                 end;
  846. X            write('(');
  847. X            eexpr(tp^.taparm);
  848. X            writeln(');')
  849. X            end;
  850. X          dhalt:
  851. X            writeln('abort();');            (* OS *)
  852. X          dnew:
  853. X            begin
  854. X            eexpr(tp^.taparm);
  855. X            write(' = (');
  856. X            etypedef(typeof(tp^.taparm));
  857. X            write(')malloc((unsigned)(');    (* LIB *)
  858. X            enewsize(tp^.taparm);
  859. X            writeln('));')
  860. X            end;
  861. X          dord:
  862. X            begin
  863. X            write('(unsigned)(');
  864. X            eexpr(tp^.taparm);
  865. X            write(')')
  866. X            end;
  867. X          dread,
  868. X          dreadln:
  869. X            begin
  870. X            txtfile := false;
  871. X            tq := tp^.taparm;
  872. X            if tq <> nil then
  873. X                begin
  874. X                tv := typeof(tq);
  875. X                if tv = typnods[ttext] then
  876. X                    begin
  877. X                    (* reading from textfile *)
  878. X                    txtfile := true;
  879. X                    tv := tq;
  880. X                    tq := tq^.tnext
  881. X                    end
  882. X                else if tv^.tt = nfileof then
  883. X                    begin
  884. X                    (* reading from other file *)
  885. X                    txtfile := typeof(tv^.tof) =
  886. X                            typnods[tchar];
  887. X                    tv := tq;
  888. X                    tq := tq^.tnext
  889. X                    end
  890. X                else begin
  891. X                    (* reading from std-input *)
  892. X                    txtfile := true;
  893. X                    tv := nil
  894. X                     end
  895. X                end
  896. X            else begin
  897. X                tv := nil;
  898. X                txtfile := true
  899. X                 end;
  900. X            if txtfile then
  901. X                begin
  902. X                (* check for special case *)
  903. X                if tq = nil then
  904. X                    goto 444;
  905. X                if (tq^.tt <> nformat) and
  906. X                        (tq^.tnext = nil) and
  907. X                        (typeletter(tq) = 'c') then
  908. X                    begin
  909. X                    (* read single char *)
  910. X                    eexpr(tq);
  911. X                    write(' = ');
  912. X                    write('Getchr(');
  913. X                    if tv = nil then
  914. X                        printid(defnams[dinput]^.lid)
  915. X                    else
  916. X                        eexpr(tv);
  917. X                    write(')');
  918. X                    if td = dreadln then
  919. X                        write(',');
  920. X                    goto 444
  921. X                    end;
  922. X                usescan := true;
  923. X                write('Fscan(');
  924. X                if tv = nil then
  925. X                    printid(defnams[dinput]^.lid)
  926. X                else
  927. X                    eexpr(tv);
  928. X                write('), ');
  929. X                (* first pass, emit format string *)
  930. X                while tq <> nil do
  931. X                    begin
  932. X                    write('Scan(', cite);
  933. X                    ch := typeletter(tq);
  934. X                    case ch of
  935. X                      'a':
  936. X                        write(percent, 's');
  937. X                      'c':
  938. X                        write(percent, 'c');
  939. X                      'd':
  940. X                        write(percent, 'ld');
  941. X                      'g':
  942. X                        write(percent, 'le')
  943. X                    end;(* case *)
  944. X                    write(cite, ', ');
  945. X                    case ch of
  946. X                      'a':
  947. X                        begin
  948. X                        eexpr(tq);
  949. X                        write('.A')
  950. X                        end;
  951. X                      'c':
  952. X                        begin
  953. X                        write('&');
  954. X                        eexpr(tq)
  955. X                        end;
  956. X                      'd':
  957. X                        write('&Tmplng');
  958. X                      'g':
  959. X                        write('&Tmpdbl')
  960. X                    end;(* case *)
  961. X                    write(')');
  962. X                    case ch of
  963. X                      'd':
  964. X                        begin
  965. X                        write(', ');
  966. X                        eexpr(tq);
  967. X                        write(' = Tmplng')
  968. X                        end;
  969. X                      'g':
  970. X                        begin
  971. X                        write(', ');
  972. X                        eexpr(tq);
  973. X                        write(' = Tmpdbl')
  974. X                        end;
  975. X                      'a',
  976. X                      'c':
  977. X                        (* no op *)
  978. X                    end;(* case *)
  979. X                    tq := tq^.tnext;
  980. X                    if tq <> nil then
  981. X                        begin
  982. X                        writeln(',');
  983. X                        indent;
  984. X                        write(tab1)
  985. X                        end
  986. X                    end;
  987. X                write(', Getx(');
  988. X                if tv = nil then
  989. X                    printid(defnams[dinput]^.lid)
  990. X                else
  991. X                    eexpr(tv);
  992. X                write(')');
  993. X                if td = dreadln then
  994. X                    write(',');
  995. X            444:
  996. X                if td = dreadln then
  997. X                    begin
  998. X                    usegetl := true;
  999. X                    write('Getl(&');
  1000. X                    if tv = nil then
  1001. X                        printid(defnams[dinput]^.lid)
  1002. X                    else
  1003. X                        eexpr(tv);
  1004. X                    write(')')
  1005. X                    end
  1006. X                end
  1007. X            else begin
  1008. X                increment;
  1009. X                while tq <> nil do
  1010. X                    begin
  1011. X                    write(voidcast, 'Fread(');
  1012. X                    eexpr(tq);
  1013. X                    write(', ');
  1014. X                    eexpr(tv);
  1015. X                    write('.fp)');
  1016. X                    tq := tq^.tnext;
  1017. X                    if tq <> nil then
  1018. X                        begin
  1019. X                        writeln(',');
  1020. X                        indent
  1021. X                        end
  1022. X                    end;
  1023. X                decrement
  1024. X                 end;
  1025. X            writeln(';')
  1026. X            end;
  1027. X          dwrite,
  1028. X          dwriteln,
  1029. X          dmessage:
  1030. X            begin
  1031. X            txtfile := false;
  1032. X            tq := tp^.taparm;
  1033. X            if tq <> nil then
  1034. X                begin
  1035. X                tv := typeof(tq);
  1036. X                if tv = typnods[ttext] then
  1037. X                    begin
  1038. X                    (* writing to textfile *)
  1039. X                    txtfile := true;
  1040. X                    tv := tq;
  1041. X                    tq := tq^.tnext
  1042. X                    end
  1043. X                else if tv^.tt = nfileof then
  1044. X                    begin
  1045. X                    (* writing to other file *)
  1046. X                    txtfile := typeof(tv^.tof) =
  1047. X                            typnods[tchar];
  1048. X                    tv := tq;
  1049. X                    tq := tq^.tnext
  1050. X                    end
  1051. X                else begin
  1052. X                    (* writing to std-output *)
  1053. X                    txtfile := true;
  1054. X                    tv := nil
  1055. X                     end
  1056. X                end
  1057. X            else begin
  1058. X                tv := nil;
  1059. X                txtfile := true
  1060. X                 end;
  1061. X            if txtfile then
  1062. X                begin
  1063. X                (* check for special case *)
  1064. X                if tq = nil then
  1065. X                    begin
  1066. X                    (* writeln whithout parameters *)
  1067. X                    if td in [dwriteln, dmessage] then
  1068. X                        begin
  1069. X                        write('Putchr(', nlchr, ', ');
  1070. X                        if tv = nil then
  1071. X                            printid(
  1072. X                              defnams[doutput]^.lid)
  1073. X                        else
  1074. X                            eexpr(tv);
  1075. X                        write(')')
  1076. X                        end;
  1077. X                    writeln(';');
  1078. X                    goto 555
  1079. X                    end
  1080. X                else if (tq^.tt <> nformat) and
  1081. X                        (tq^.tnext = nil) then
  1082. X                    if typeletter(tq) = 'c' then
  1083. X                        begin
  1084. X                        (* print single char *)
  1085. X                        write('Putchr(');
  1086. X                        eexpr(tq);
  1087. X                        write(', ');
  1088. X                        if tv = nil then
  1089. X                            printid(
  1090. X                              defnams[doutput]^.lid)
  1091. X                        else
  1092. X                            eexpr(tv);
  1093. X                        write(')');
  1094. X                        if td = dwriteln then
  1095. X                            begin
  1096. X                            write(',Putchr(',
  1097. X                                nlchr, ', ');
  1098. X                            if tv = nil then
  1099. X                             printid(
  1100. X                              defnams[doutput]^.lid)
  1101. X                            else
  1102. X                                eexpr(tv);
  1103. X                            write(')');
  1104. X                            end;
  1105. X                        writeln(';');
  1106. X                        goto 555
  1107. X                        end;
  1108. X                tx := nil;
  1109. X                write(voidcast, 'fprintf(');    (* LIB *)
  1110. X                if td = dmessage then
  1111. X                    write('stderr, ')
  1112. X                else begin
  1113. X                    if tv = nil then
  1114. X                        printid(defnams[doutput]^.lid)
  1115. X                    else
  1116. X                        eexpr(tv);
  1117. X                    write('.fp, ')
  1118. X                     end;
  1119. X                write(cite);
  1120. X                tx := tq;    (* remember 1:st parm *)
  1121. X                (* first pass, emit format string *)
  1122. X                while tq <> nil do
  1123. X                    begin
  1124. X                    eformat(tq);
  1125. X                    tq := tq^.tnext
  1126. X                    end;
  1127. X                if (td = dmessage) or (td = dwriteln) then
  1128. X                    write('\n');
  1129. X                write(cite);
  1130. X                (* second pass, add parameters *)
  1131. X                tq := tx;
  1132. X                while tq <> nil do
  1133. X                    begin
  1134. X                    ewrite(tq);
  1135. X                    tq := tq^.tnext
  1136. X                    end;
  1137. X                write('), Putl(');
  1138. X                if tv = nil then
  1139. X                    printid(defnams[doutput]^.lid)
  1140. X                else
  1141. X                    eexpr(tv);
  1142. X                if td = dwrite then
  1143. X                    write(', 0)')
  1144. X                else
  1145. X                    write(', 1)')
  1146. X                end
  1147. X            else begin
  1148. X                increment;
  1149. X                tx := typeof(tv);
  1150. X                if tx = typnods[ttext] then
  1151. X                    tx := typnods[tchar]
  1152. X                else if tx^.tt = nfileof then
  1153. X                    tx := typeof(tx^.tof)
  1154. X                else
  1155. X                    fatal(etree);
  1156. X                while tq <> nil do
  1157. X                    begin
  1158. X                    if (tq^.tt in [nid, nindex, nselect,
  1159. X                            nderef]) and
  1160. X                        (tx = typeof(tq)) then
  1161. X                        begin
  1162. X                        write(voidcast, 'Fwrite(');
  1163. X                        eexpr(tq)
  1164. X                        end
  1165. X                    else begin
  1166. X                        if tx^.tt = nsetof then
  1167. X                            begin
  1168. X                            usescpy := true;
  1169. X                            write('Setncpy(');
  1170. X                            eselect(tv);
  1171. X                            write('buf.S, ');
  1172. X                            eexpr(tq);
  1173. X                            if typeof(tp^.trhs) =
  1174. X                               typnods[tset] then
  1175. X                                eexpr(tq)
  1176. X                            else begin
  1177. X                                eselect(tq);
  1178. X                                write('S')
  1179. X                                 end;
  1180. X                            write(', sizeof(');
  1181. X                            eexpr(tv);
  1182. X                            write('.buf))');
  1183. X                            end
  1184. X                        else begin
  1185. X                            eexpr(tv);
  1186. X                            write('.buf = ');
  1187. X                            eexpr(tq)
  1188. X                             end;
  1189. X                        write(', Fwrite(');
  1190. X                        eexpr(tv);
  1191. X                        write('.buf');
  1192. X                         end;
  1193. X                    write(', ');
  1194. X                    eexpr(tv);
  1195. X                    write('.fp)');
  1196. X                    tq := tq^.tnext;
  1197. X                    if tq <> nil then
  1198. X                        begin
  1199. X                        writeln(',');
  1200. X                        indent
  1201. X                        end
  1202. X                    end;
  1203. X                decrement
  1204. X                 end;
  1205. X            writeln(';');
  1206. X        555:
  1207. X            end;
  1208. X          dclose:
  1209. X            begin
  1210. X            tq := typeof(tp^.taparm);
  1211. X            txtfile := tq = typnods[ttext];
  1212. X            if (not txtfile) and (tq^.tt = nfileof) then
  1213. X                if typeof(tq^.tof) = typnods[tchar] then
  1214. X                    txtfile := true;
  1215. X            if txtfile then
  1216. X                write('Closex(')
  1217. X            else
  1218. X                write('Close(');
  1219. X            eexpr(tp^.taparm);
  1220. X            writeln(');');
  1221. X            end;
  1222. X          dreset,
  1223. X          drewrite:
  1224. X            begin
  1225. X            tq := typeof(tp^.taparm);
  1226. X            txtfile := tq = typnods[ttext];
  1227. X            if (not txtfile) and (tq^.tt = nfileof) then
  1228. X                if typeof(tq^.tof) = typnods[tchar] then
  1229. X                    txtfile := true;
  1230. X            if txtfile then
  1231. X                if td = dreset then
  1232. X                    write('Resetx(')
  1233. X                else
  1234. X                    write('Rewritex(')
  1235. X            else
  1236. X                if td = dreset then
  1237. X                    write('Reset(')
  1238. X                else
  1239. X                    write('Rewrite(');
  1240. X            eexpr(tp^.taparm);
  1241. X            write(', ');
  1242. X            tq := tp^.taparm^.tnext;
  1243. X            if tq = nil then
  1244. X                write('NULL')
  1245. X            else begin
  1246. X                tq := typeof(tq);
  1247. X                if tq = typnods[tchar] then
  1248. X                    begin
  1249. X                    write(cite);
  1250. X                    ch := chr(cvalof(tp^.taparm^.tnext));
  1251. X                    if (ch = bslash) or (ch = cite) then
  1252. X                        write(bslash);
  1253. X                    write(ch, cite)
  1254. X                    end
  1255. X                else if tq = typnods[tstring] then
  1256. X                    eexpr(tp^.taparm^.tnext)
  1257. X                else  if tq^.tt in [narray, nconfarr] then
  1258. X                     begin
  1259. X                    eexpr(tp^.taparm^.tnext);
  1260. X                    write('.A')
  1261. X                     end
  1262. X                else
  1263. X                    fatal(etree)
  1264. X                 end;
  1265. X            writeln(');')
  1266. X            end;
  1267. X          darctan:
  1268. X            begin
  1269. X            write('atan(');    (* LIB *)
  1270. X            if typeof(tp^.taparm) <> typnods[treal] then
  1271. X                write(dblcast);
  1272. X            eexpr(tp^.taparm);
  1273. X            write(')')
  1274. X            end;
  1275. X          dln:
  1276. X            begin
  1277. X            write('log(');    (* LIB *)
  1278. X            if typeof(tp^.taparm) <> typnods[treal] then
  1279. X                write(dblcast);
  1280. X            eexpr(tp^.taparm);
  1281. X            write(')')
  1282. X            end;
  1283. X          dexp:
  1284. X            begin
  1285. X            write('exp(');    (* LIB *)
  1286. X            if typeof(tp^.taparm) <> typnods[treal] then
  1287. X                write(dblcast);
  1288. X            eexpr(tp^.taparm);
  1289. X            write(')')
  1290. X            end;
  1291. X          dcos,
  1292. X          dsin,
  1293. X          dsqrt:
  1294. X            begin
  1295. X            eexpr(tp^.tcall);    (* LIB *)
  1296. X            write('(');
  1297. X            if typeof(tp^.taparm) <> typnods[treal] then
  1298. X                write(dblcast);
  1299. X            eexpr(tp^.taparm);
  1300. X            write(')')
  1301. X            end;
  1302. X          dtan:
  1303. X            begin
  1304. X            write('atan(');        (* LIB *)
  1305. X            if typeof(tp^.taparm) <> typnods[treal] then
  1306. X                write(dblcast);
  1307. X            eexpr(tp^.taparm);
  1308. X            write(')')
  1309. X            end;
  1310. X          dsucc,
  1311. X          dpred:
  1312. X            begin
  1313. X            tq := typeof(tp^.taparm);
  1314. X            if tq^.tt = nsubrange then
  1315. X                if tq^.tup^.tt = nconfarr then
  1316. X                    tq := typeof(tq^.tup^.tindtyp)
  1317. X                else
  1318. X                    tq := typeof(tq^.tlo);
  1319. X            if (tq = typnods[tinteger]) or
  1320. X                        (tq = typnods[tchar]) then
  1321. X                begin
  1322. X                write('((');
  1323. X                eexpr(tp^.taparm);
  1324. X                if td = dpred then
  1325. X                    write(')-1)')
  1326. X                else
  1327. X                    write(')+1)')
  1328. X                end
  1329. X            else begin
  1330. X                (* some sort of scalar type, casting needed *)
  1331. X                write('(');
  1332. X                tq := tq^.tup;
  1333. X                if tq^.tt = ntype then
  1334. X                    begin
  1335. X                    (* cast only if it is a named type *)
  1336. X                    write('(');
  1337. X                    printid(tq^.tidl^.tsym^.lid);
  1338. X                    write(')')
  1339. X                    end;
  1340. X                write('((int)(');
  1341. X                eexpr(tp^.taparm);
  1342. X                if td = dpred then
  1343. X                    write(')-1))')
  1344. X                else
  1345. X                    write(')+1))')
  1346. X                 end
  1347. X            end;
  1348. X          dodd:
  1349. X            begin
  1350. X            write('(');
  1351. X            printid(defnams[dboolean]^.lid);
  1352. X            write(')((');
  1353. X            eexpr(tp^.taparm);
  1354. X            write(') & 1)')
  1355. X            end;
  1356. X          dsqr:
  1357. X            begin
  1358. X            tq := typeof(tp^.taparm);
  1359. X            if (tq = typnods[tinteger]) or (tq^.tt = nsubrange) then
  1360. X                begin
  1361. X                write('((');
  1362. X                eexpr(tp^.taparm);
  1363. X                write(') * (');
  1364. X                eexpr(tp^.taparm);
  1365. X                write('))')
  1366. X                end
  1367. X            else begin
  1368. X                write('pow(');    (* LIB *)
  1369. X                if typeof(tp^.taparm) <> typnods[treal] then
  1370. X                    write(dblcast);
  1371. X                eexpr(tp^.taparm);
  1372. X                write(', 2.0)')
  1373. X                 end
  1374. X            end;
  1375. X          dround:
  1376. X            begin
  1377. X            write('Round(');
  1378. X            eexpr(tp^.taparm);
  1379. X            write(')')
  1380. X            end;
  1381. X          dtrunc:
  1382. X            begin
  1383. X            write('Trunc(');
  1384. X            eexpr(tp^.taparm);
  1385. X            write(')')
  1386. X            end;
  1387. X          dpack:
  1388. X            begin
  1389. X            tq := typeof(tp^.taparm);
  1390. X            tx := typeof(tp^.taparm^.tnext^.tnext);
  1391. X            write('{    ', registr, inttyp, tab1, '_j, _i = ');
  1392. X            if not arithexpr(tp^.taparm^.tnext) then
  1393. X                write('(int)');
  1394. X            eexpr(tp^.taparm^.tnext);
  1395. X            if tx^.tt = narray then
  1396. X                write(' - ', clower(tq^.taindx):1);
  1397. X            writeln(';');
  1398. X            indent;
  1399. X            write('    for (_j = 0; _j < ');
  1400. X            if tq^.tt = nconfarr then
  1401. X                begin
  1402. X                write('(int)(');
  1403. X                printid(tx^.tcindx^.thi^.tsym^.lid);
  1404. X                write(')')
  1405. X                end
  1406. X            else
  1407. X                write(crange(tx^.taindx):1);
  1408. X            writeln('; )');
  1409. X            indent;
  1410. X            write(tab1);
  1411. X            eexpr(tp^.taparm^.tnext^.tnext);
  1412. X            write('.A[_j++] = ');
  1413. X            eexpr(tp^.taparm);
  1414. X            writeln('.A[_i++];');
  1415. X            indent;
  1416. X            writeln('}')
  1417. X            end;
  1418. X          dunpack:
  1419. X            begin
  1420. X            tq := typeof(tp^.taparm);
  1421. X            tx := typeof(tp^.taparm^.tnext);
  1422. X            write('{   ', registr, inttyp, tab1, '_j, _i = ');
  1423. X            if not arithexpr(tp^.taparm^.tnext^.tnext) then
  1424. X                write('(int)');
  1425. X            eexpr(tp^.taparm^.tnext^.tnext);
  1426. X            if tx^.tt <> nconfarr then
  1427. X                write(' - ', clower(tx^.taindx):1);
  1428. X            writeln(';');
  1429. X            indent;
  1430. X            write('    for (_j = 0; _j < ');
  1431. X            if tq^.tt = nconfarr then
  1432. X                begin
  1433. X                write('(int)(');
  1434. X                printid(tq^.tcindx^.thi^.tsym^.lid);
  1435. X                write(')')
  1436. X                end
  1437. X            else
  1438. X                write(crange(tq^.taindx):1);
  1439. X            writeln('; )');
  1440. X            indent;
  1441. X            write(tab1);
  1442. X            eexpr(tp^.taparm^.tnext);
  1443. X            write('.A[_i++] = ');
  1444. X            eexpr(tp^.taparm);
  1445. X            writeln('.A[_j++];');
  1446. X            indent;
  1447. X            writeln('}')
  1448. X            end;
  1449. X        end (* case *)
  1450. X    end;    (* epredef *)
  1451. X
  1452. X    procedure eaddr(tp : treeptr);
  1453. X
  1454. X    begin
  1455. X        write('&');
  1456. X        if not(tp^.tt in [nid, nselect, nindex, nderef]) then
  1457. X            error(evarpar);
  1458. X        eexpr(tp)
  1459. X    end;
  1460. X
  1461. X    (*    Emit code for a subroutine call.            *)
  1462. X    procedure ecall(tp : treeptr);
  1463. X
  1464. X    var    tf, tq, tx    : treeptr;
  1465. X
  1466. X    begin
  1467. X        (* find first formal parameter id *)
  1468. X        tf := idup(tp^.tcall);
  1469. X        case tf^.tt of
  1470. X          nproc,
  1471. X          nfunc:
  1472. X            tf := tf^.tsubpar;
  1473. X          nparproc,
  1474. X          nparfunc:
  1475. X            tf := tf^.tparparm
  1476. X        end;(* case *)
  1477. X        if tf <> nil then
  1478. X            begin
  1479. X            case tf^.tt of
  1480. X              nvalpar,
  1481. X              nvarpar:
  1482. X                tf := tf^.tidl;
  1483. X              nparproc,
  1484. X              nparfunc:
  1485. X                tf := tf^.tparid
  1486. X            end (* case *)
  1487. X            end;
  1488. X        (* emit called function name *)
  1489. X        eexpr(tp^.tcall);
  1490. X        write('(');
  1491. X        (* emit actual parameters *)
  1492. X        tq := tp^.taparm;
  1493. X        while tq <> nil do
  1494. X            begin
  1495. X            if tf^.tup^.tt in [nparfunc, nparproc] then
  1496. X                begin
  1497. X                (* single subroutine-nid converted to ncall *)
  1498. X                if tq^.tt = ncall then
  1499. X                    printid(tq^.tcall^.tsym^.lid)
  1500. X                else
  1501. X                    printid(tq^.tsym^.lid)
  1502. X                end
  1503. X            else begin
  1504. X                tx := typeof(tq);
  1505. X                if tx = typnods[tboolean] then
  1506. X                    begin
  1507. X                    tx := tq;
  1508. X                    while tx^.tt = nuplus do
  1509. X                        tx := tx^.texps;
  1510. X                    if tx^.tt in [nin .. nor, nand, nnot]
  1511. X                                    then
  1512. X                        begin
  1513. X                        write('(');
  1514. X                        printid(defnams[dboolean]^.lid);
  1515. X                        write(')(');
  1516. X                        eexpr(tq);
  1517. X                        write(')')
  1518. X                        end
  1519. X                    else
  1520. X                        eexpr(tq);
  1521. X                    end
  1522. X                else if (tx = typnods[tstring]) or
  1523. X                        (tx = typnods[tset]) then
  1524. X                    begin
  1525. X                    (* cast literal to proper type *)
  1526. X                    write('*((');
  1527. X                    etypedef(tf^.tup^.tbind);
  1528. X                    write(' *)');
  1529. X                    if tx = typnods[tset] then
  1530. X                        begin
  1531. X                        dropset := true;
  1532. X                        eexpr(tq);
  1533. X                        dropset := false
  1534. X                        end
  1535. X                    else
  1536. X                        eexpr(tq);
  1537. X                    write(')')
  1538. X                    end
  1539. X                else if tx = typnods[tnil] then
  1540. X                    begin
  1541. X                    write('(');
  1542. X                    etypedef(tf^.tup^.tbind);
  1543. X                    write(')NIL')
  1544. X                    end
  1545. X                else if tf^.tup^.tbind^.tt = nconfarr then
  1546. X                    begin
  1547. X                    write('(struct ');
  1548. X                    printid(tf^.tup^.tbind^.tcuid);
  1549. X                    write(' *)&');
  1550. X                    eexpr(tq);
  1551. X                    (* add upper bound of actual value *)
  1552. X                    if tq^.tnext = nil then
  1553. X                        write(', ',
  1554. X                            crange(tx^.taindx):1)
  1555. X                    end
  1556. X                else begin
  1557. X                    if tf^.tup^.tt = nvarpar then
  1558. X                        eaddr(tq)
  1559. X                    else
  1560. X                        eexpr(tq)
  1561. X                     end
  1562. X                end;
  1563. X            tq := tq^.tnext;
  1564. X            if tq <> nil then
  1565. X                begin
  1566. X                write(', ');
  1567. X                (* next formal parameter *)
  1568. X                if tf^.tnext = nil then
  1569. X                    begin
  1570. X                    tf := tf^.tup^.tnext;
  1571. X                    case tf^.tt of
  1572. X                      nvalpar,
  1573. X                      nvarpar:
  1574. X                        tf := tf^.tidl;
  1575. X                      nparproc,
  1576. X                      nparfunc:
  1577. X                        tf := tf^.tparid
  1578. X                    end (* case *)
  1579. X                    end
  1580. X                else
  1581. X                    tf := tf^.tnext;
  1582. X                end;
  1583. X            end;
  1584. X        write(')')
  1585. X    end;    (* ecall *)
  1586. X
  1587. X    (*    Emit code for a general expression.            *)
  1588. X    procedure eexpr;
  1589. X
  1590. X    label    999;
  1591. X
  1592. X    var    tq    : treeptr;
  1593. X        flag    : boolean;
  1594. X
  1595. X        function constset(tp : treeptr) : boolean;
  1596. X
  1597. X            function constxps(tp : treeptr) : boolean;
  1598. X            begin
  1599. X                case tp^.tt of
  1600. X                  nrange:
  1601. X                    if constxps(tp^.texpr) then
  1602. X                        constxps := constxps(tp^.texpl)
  1603. X                    else
  1604. X                        constxps := false;
  1605. X                  nempty,
  1606. X                  ninteger,
  1607. X                  nchar:
  1608. X                    constxps := true;
  1609. X                  nid:
  1610. X                    begin
  1611. X                    tp := idup(tp);
  1612. X                    constxps := (tp^.tt = nconst)
  1613. X                            or (tp^.tt = nscalar)
  1614. X                    end;
  1615. X                  nin, neq, nne, nlt, nle, ngt, nge, nor,
  1616. X                  nplus, nminus, nand, nmul, ndiv, nmod,
  1617. X                  nquot, nnot, numinus, nuplus, nset,    
  1618. X                  nindex, nselect, nderef, ncall,
  1619. X                  nreal, nstring, nnil:
  1620. X                    constxps := false
  1621. X                end (* case *)
  1622. X            end;
  1623. X
  1624. X        begin
  1625. X            constset := true;
  1626. X            while tp <> nil do
  1627. X                if constxps(tp) then
  1628. X                    tp := tp^.tnext
  1629. X                else begin
  1630. X                    constset := false;
  1631. X                    tp := nil
  1632. X                    end
  1633. X        end;
  1634. X
  1635. X    begin    (* eexpr *)
  1636. X        donearr := false;
  1637. X        if tp^.tt in [nplus, nminus, nmul, nle, nge, neq, nne] then
  1638. X            begin
  1639. X            tq := typeof(tp^.texpl);
  1640. X            if (tq^.tt in [nset, nsetof]) or
  1641. X                        (tq = typnods[tset]) then
  1642. X                begin
  1643. X                (* set operations *)
  1644. X                case tp^.tt of
  1645. X                  nplus:
  1646. X                    begin
  1647. X                    setused := true;
  1648. X                    useunion := true;
  1649. X                    write('Union')
  1650. X                    end;
  1651. X                  nminus:
  1652. X                    begin
  1653. X                    setused := true;
  1654. X                    usediff := true;
  1655. X                    write('Diff')
  1656. X                    end;
  1657. X                  nmul:
  1658. X                    begin
  1659. X                    setused := true;
  1660. X                    useintr := true;
  1661. X                    write('Inter')
  1662. X                    end;
  1663. X                  neq:
  1664. X                    begin
  1665. X                    useseq := true;
  1666. X                    write('Eq')
  1667. X                    end;
  1668. X                  nne:
  1669. X                    begin
  1670. X                    usesne := true;
  1671. X                    write('Ne')
  1672. X                    end;
  1673. X                  nge:
  1674. X                    begin
  1675. X                    usesge := true;
  1676. X                    write('Ge')
  1677. X                    end;
  1678. X                  nle:
  1679. X                    begin
  1680. X                    usesle := true;
  1681. X                    write('Le')
  1682. X                    end
  1683. X                end;(* case *)
  1684. X                if tp^.tt in [nplus, nminus, nmul] then
  1685. X                    dropset := false;
  1686. X                write('(');
  1687. X                eexpr(tp^.texpl);
  1688. X                if tq^.tt = nsetof then
  1689. X                    write('.S');
  1690. X                write(', ');
  1691. X                eexpr(tp^.texpr);
  1692. X                tq := typeof(tp^.texpr);
  1693. X                if tq^.tt = nsetof then
  1694. X                    write('.S');
  1695. X                write(')');
  1696. X                goto 999
  1697. X                end
  1698. X            end;
  1699. X        if tp^.tt in [neq, nne, ngt, nlt, nge, nle] then
  1700. X            begin
  1701. X            tq := typeof(tp^.texpl);
  1702. X            if tq^.tt = nconfarr then
  1703. X                fatal(ecmpconf);
  1704. X            if (tq^.tt in [nstring, narray]) or
  1705. X                        (tq = typnods[tstring]) then
  1706. X                begin
  1707. X                write('Cmpstr(');
  1708. X                eexpr(tp^.texpl);
  1709. X                if tq^.tt = narray then
  1710. X                    write('.A');
  1711. X                write(', ');
  1712. X                tq := typeof(tp^.texpr);
  1713. X                if tq^.tt = nconfarr then
  1714. X                    fatal(ecmpconf);
  1715. X                eexpr(tp^.texpr);
  1716. X                if tq^.tt = narray then
  1717. X                    write('.A');
  1718. X                write(')');
  1719. X                case tp^.tt of
  1720. X                  neq:
  1721. X                    write(' == ');
  1722. X                  nne:
  1723. X                    write(' != ');
  1724. X                  ngt:
  1725. X                    write(' > ');
  1726. X                  nlt:
  1727. X                    write(' < ');
  1728. X                  nge:
  1729. X                    write(' >= ');
  1730. X                  nle:
  1731. X                    write(' <= ');
  1732. X                end;(* case *)
  1733. X                write('0');
  1734. X                goto 999
  1735. X                end
  1736. X            end;
  1737. X        case tp^.tt of
  1738. X          neq, nne, nlt, nle,
  1739. X          ngt, nge, nor, nand, nplus, nminus,
  1740. X          nmul, ndiv, nmod, nquot:
  1741. X            begin
  1742. X            flag := cprio[tp^.tt] > cprio[tp^.texpl^.tt];
  1743. X            if (tp^.tt in [nlt, nle, ngt, nge]) and
  1744. X                    not arithexpr(tp^.texpl) then
  1745. X                begin
  1746. X                write('(int)');
  1747. X                flag := true
  1748. X                end;
  1749. X            if flag then
  1750. X                write('(');
  1751. X            eexpr(tp^.texpl);
  1752. X            if flag then
  1753. X                write(')');
  1754. X            case tp^.tt of
  1755. X              neq:
  1756. X                write(' == ');
  1757. X              nne:
  1758. X                write(' != ');
  1759. X              nlt:
  1760. X                write(' < ');
  1761. X              nle:
  1762. X                write(' <= ');
  1763. X              ngt:
  1764. X                write(' > ');
  1765. X              nge:
  1766. X                write(' >= ');
  1767. X              nor:
  1768. X                write(' || ');
  1769. X              nand:
  1770. X                write(' && ');
  1771. X              nplus:
  1772. X                write(' + ');
  1773. X              nminus:
  1774. X                write(' - ');
  1775. X              nmul:
  1776. X                write(' * ');
  1777. X              ndiv:
  1778. X                write(' / ');
  1779. X              nmod:
  1780. X                write(' % ');
  1781. X              nquot:
  1782. X                begin
  1783. X                write(' / ((');
  1784. X                printid(defnams[dreal]^.lid);
  1785. X                write(')')
  1786. X                end
  1787. X            end;(* case *)
  1788. X            flag := cprio[tp^.tt] > cprio[tp^.texpr^.tt];
  1789. X            if (tp^.tt in [nlt, nle, ngt, nge]) and
  1790. X                    not arithexpr(tp^.texpr) then
  1791. X                begin
  1792. X                write('(int)');
  1793. X                flag := true
  1794. X                end;
  1795. X            if flag then
  1796. X                write('(');
  1797. X            eexpr(tp^.texpr);
  1798. X            if flag then
  1799. X                write(')');
  1800. X            if tp^.tt = nquot then
  1801. X                write(')')
  1802. X            end;
  1803. X
  1804. X          nuplus, numinus, nnot:
  1805. X            begin
  1806. X            case tp^.tt of
  1807. X              numinus:
  1808. X                write('-');
  1809. X              nnot:
  1810. X                write('!');
  1811. X              nuplus:
  1812. X            end;(* case *)
  1813. X            flag := cprio[tp^.tt] >= cprio[tp^.texps^.tt];
  1814. X            if flag then
  1815. X                write('(');
  1816. X            eexpr(tp^.texps);
  1817. X            if flag then
  1818. X                write(')');
  1819. X            end;
  1820. X          
  1821. X          nin:
  1822. X            begin
  1823. X            usememb := true;
  1824. X            write('Member((unsigned)(');
  1825. X            eexpr(tp^.texpl);
  1826. X            write('), ');
  1827. X            dropset := true;    (* no need to save set-expr *)
  1828. X            eexpr(tp^.texpr);
  1829. X            dropset := false;
  1830. X            tq := typeof(tp^.texpr);
  1831. X            if tq^.tt = nsetof then
  1832. X                write('.S');
  1833. X            write(')')
  1834. X            end;
  1835. X
  1836. X          nassign:
  1837. X            begin
  1838. X            tq := typeof(tp^.trhs);
  1839. X            if tq = typnods[tstring] then
  1840. X                begin
  1841. X                write(voidcast, 'strncpy(');
  1842. X                eexpr(tp^.tlhs);
  1843. X                write('.A, ');
  1844. X                eexpr(tp^.trhs);
  1845. X                write(', sizeof(');
  1846. X                eexpr(tp^.tlhs);
  1847. X                write('.A))')
  1848. X                end
  1849. X            else if tq = typnods[tboolean] then
  1850. X                begin
  1851. X                eexpr(tp^.tlhs);
  1852. X                write(' = ');
  1853. X                tq := tp^.trhs;
  1854. X                while tq^.tt = nuplus do
  1855. X                    tq := tq^.texps;
  1856. X                if tq^.tt in [nin .. nor, nand, nnot] then
  1857. X                    begin
  1858. X                    write('(');
  1859. X                    printid(defnams[dboolean]^.lid);
  1860. X                    write(')(');
  1861. X                    eexpr(tq);
  1862. X                    write(')')
  1863. X                    end
  1864. X                else
  1865. X                    eexpr(tq)
  1866. X                end
  1867. X            else if tq = typnods[tnil] then
  1868. X                begin
  1869. X                eexpr(tp^.tlhs);
  1870. X                write(' = (');
  1871. X                etypedef(typeof(tp^.tlhs));
  1872. X                write(')NIL')
  1873. X                end
  1874. X            else begin
  1875. X                tq := typeof(tp^.tlhs);
  1876. X                if tq^.tt = nsetof then
  1877. X                    begin
  1878. X                    usescpy := true;
  1879. X                    write('Setncpy(');
  1880. X                    eselect(tp^.tlhs);
  1881. X                    write('S, ');
  1882. X                    dropset := true;
  1883. X                    tq := typeof(tp^.trhs);
  1884. X                    if tq = typnods[tset] then
  1885. X                        eexpr(tp^.trhs)
  1886. X                    else begin
  1887. X                        eselect(tp^.trhs);
  1888. X                        write('S')
  1889. X                         end;
  1890. X                    dropset := false;
  1891. X                    write(', sizeof(');
  1892. X                    eselect(tp^.tlhs);
  1893. X                    write('S))')
  1894. X                    end
  1895. X                else begin
  1896. X                    eexpr(tp^.tlhs);
  1897. X                    write(' = ');
  1898. X                    eexpr(tp^.trhs)
  1899. X                     end
  1900. X                 end
  1901. X            end;
  1902. X
  1903. X          ncall:
  1904. X            begin
  1905. X            tq := idup(tp^.tcall);
  1906. X            if (tq^.tt in [nfunc, nproc]) and
  1907. X                    (tq^.tsubstmt <> nil) then
  1908. X                if tq^.tsubstmt^.tt = npredef then
  1909. X                    epredef(tq, tp)
  1910. X                else
  1911. X                    ecall(tp)
  1912. X            else
  1913. X                ecall(tp)
  1914. X            end;
  1915. X
  1916. X          nselect:
  1917. X            begin
  1918. X            eselect(tp^.trecord);
  1919. X            eexpr(tp^.tfield)
  1920. X            end;
  1921. X          nindex:
  1922. X            begin
  1923. X            eselect(tp^.tvariable);
  1924. X            write('A[');
  1925. X            tq := tp^.toffset;
  1926. X            if arithexpr(tq) then
  1927. X                eexpr(tq)
  1928. X            else begin
  1929. X                write('(int)(');
  1930. X                eexpr(tq);
  1931. X                write(')')
  1932. X                 end;
  1933. X            tq := typeof(tp^.tvariable);
  1934. X            if tq^.tt = narray then
  1935. X                if clower(tq^.taindx) <> 0 then
  1936. X                    begin
  1937. X                    write(' - ');
  1938. X                    tq := typeof(tq^.taindx);
  1939. X                    if tq^.tt = nsubrange then
  1940. X                        if arithexpr(tq^.tlo) then
  1941. X                            eexpr(tq^.tlo)
  1942. X                        else begin
  1943. X                            write('(int)(');
  1944. X                            eexpr(tq^.tlo);
  1945. X                            write(')')
  1946. X                             end
  1947. X                    else 
  1948. X                        fatal(etree)
  1949. X                    end;
  1950. X            write(']')
  1951. X            end;
  1952. X          nderef:
  1953. X            begin
  1954. X            tq := typeof(tp^.texps);
  1955. X            if (tq^.tt = nfileof) or
  1956. X                 ((tq^.tt = npredef) and (tq^.tdef = dtext)) then
  1957. X                begin
  1958. X                (* using a file-variable as pointer *)
  1959. X                eexpr(tp^.texps);
  1960. X                write('.buf')
  1961. X                end
  1962. X            else if doarrow = 0 then
  1963. X                begin
  1964. X                write('*');
  1965. X                eexpr(tp^.texps)
  1966. X                end
  1967. X            else begin
  1968. X                eexpr(tp^.texps);
  1969. X                write('->');
  1970. X                donearr := true
  1971. X                 end
  1972. X            end;
  1973. X          nid:
  1974. X            begin
  1975. X            (* add pointer-dereference if this id is declared as a
  1976. X               var-parameter or as a procedure-parameter *)
  1977. X            tq := idup(tp);
  1978. X            if tq^.tt = nvarpar then
  1979. X                begin
  1980. X                if (doarrow = 0) or
  1981. X                        (tq^.tattr = areference) then
  1982. X                    begin
  1983. X                    write('(*');
  1984. X                    printid(tp^.tsym^.lid);
  1985. X                    write(')')
  1986. X                    end
  1987. X                else begin
  1988. X                    printid(tp^.tsym^.lid);
  1989. X                    write('->');
  1990. X                    donearr := true
  1991. X                     end
  1992. X                end
  1993. X            else if (tq^.tt = nconst) and conflag then
  1994. X                write(cvalof(tp):1)
  1995. X            else if tq^.tt in [nparproc, nparfunc] then
  1996. X                begin
  1997. X                write('(*');
  1998. X                printid(tp^.tsym^.lid);
  1999. X                write(')')
  2000. X                end
  2001. X            else
  2002. X                printid(tp^.tsym^.lid);
  2003. X            end;
  2004. X          nchar:
  2005. X            printchr(tp^.tsym^.lchar);
  2006. X          ninteger:
  2007. X            write(tp^.tsym^.linum:1);
  2008. X          nreal:
  2009. X            printtok(tp^.tsym^.lfloat);
  2010. X          nstring:
  2011. X            printstr(tp^.tsym^.lstr);
  2012. X          nset:
  2013. X            if constset(tp^.texps) then
  2014. X                begin
  2015. X                (* save set expression for initialization *)
  2016. X                write('Conset[', setcnt:1, ']');
  2017. X                setcnt := setcnt + 1;
  2018. X                tq := mknode(nset);
  2019. X                tq^.tnext := setlst;
  2020. X                setlst := tq;
  2021. X                tq^.texps := tp^.texps
  2022. X                end
  2023. X            else begin
  2024. X                increment;
  2025. X                flag := dropset;
  2026. X                (* if a set-constructor is used in an
  2027. X                   expression involving + - *  it will need to
  2028. X                   be saved temporarily (by Saveset) but often
  2029. X                   we can simply forget the set-value when we
  2030. X                   have finished using it *)
  2031. X                if dropset then
  2032. X                    dropset := false
  2033. X                else
  2034. X                    write('Saveset(');
  2035. X                write('(Tmpset = Newset(), ');
  2036. X                tq := tp^.texps;
  2037. X                while tq <> nil do
  2038. X                    begin
  2039. X                    case tq^.tt of
  2040. X                      nrange:
  2041. X                        begin
  2042. X                        usemksub := true;
  2043. X                        write(voidcast, 'Mksubr(');
  2044. X                        write('(unsigned)(');
  2045. X                        eexpr(tq^.texpl);
  2046. X                        write('), ');
  2047. X                        write('(unsigned)(');
  2048. X                        eexpr(tq^.texpr);
  2049. X                        write('), Tmpset)')
  2050. X                        end;
  2051. X                      nin, neq, nne, nlt, nle, ngt, nge,
  2052. X                      nor, nand, nmul, ndiv, nmod, nquot,
  2053. X                      nplus, nminus, nnot, numinus, nuplus, 
  2054. X                      nindex, nselect, nderef, ncall,
  2055. X                      ninteger, nchar, nid:
  2056. X                        begin
  2057. X                        useins := true;
  2058. X                        write(voidcast, 'Insmem(');
  2059. X                        write('(unsigned)(');
  2060. X                        eexpr(tq);
  2061. X                        write('), Tmpset)')
  2062. X                        end
  2063. X                    end;(* case *)
  2064. X                    tq := tq^.tnext;
  2065. X                    if tq <> nil then
  2066. X                        begin
  2067. X                        writeln(',');
  2068. X                        indent
  2069. X                        end
  2070. X                    end;
  2071. X                write(', Tmpset)');
  2072. X                if not flag then
  2073. X                    begin
  2074. X                    write(')');
  2075. X                    setused := true
  2076. X                    end;
  2077. X                decrement
  2078. X                 end;
  2079. X          nnil:
  2080. X            begin
  2081. X            tq := tp;
  2082. X            repeat
  2083. X                tq := tq^.tup
  2084. X            until    tq^.tt in [neq, nne, ncall, nassign, npgm];
  2085. X            if tq^.tt in [neq, nne] then
  2086. X                begin
  2087. X                if typeof(tq^.texpl) = typnods[tnil] then
  2088. X                    tq := typeof(tq^.texpr)
  2089. X                else
  2090. X                    tq := typeof(tq^.texpl);
  2091. X                if tq^.tt = nptr then
  2092. X                    begin
  2093. X                    write('(');
  2094. X                    etypedef(tq);
  2095. X                    write(')')
  2096. X                    end
  2097. X                end;
  2098. X            write('NIL')
  2099. X            end;
  2100. X        end;(* case *)
  2101. X    999:
  2102. X    end;    (* eexpr *)
  2103. X
  2104. X    (*    Emit constant definitions.                *)
  2105. X    procedure econst(tp : treeptr);
  2106. X
  2107. X    var    sp    : symptr;
  2108. X
  2109. X    begin
  2110. X        while tp <> nil do
  2111. X            begin
  2112. X            sp := tp^.tidl^.tsym;
  2113. X            if sp^.lid^.inref > 1 then
  2114. X                sp^.lid := mkrename('X', sp^.lid);
  2115. X            if tp^.tbind^.tt = nstring then
  2116. X                begin
  2117. X                (* string constants emitted as
  2118. X                   static local variables *)
  2119. X                indent;
  2120. X                write(static, chartyp, tab1);
  2121. X                printid(sp^.lid);
  2122. X                write('[]    = ');
  2123. X                eexpr(tp^.tbind);
  2124. X                writeln(';')
  2125. X                end
  2126. X            else begin
  2127. X                (* all other constants emitted as
  2128. X                   preprocessor # defines *)
  2129. X                write(define);
  2130. X                printid(sp^.lid);
  2131. X                write(space);
  2132. X                eexpr(tp^.tbind);
  2133. X                writeln
  2134. X                end;
  2135. X            tp := tp^.tnext
  2136. X            end
  2137. X    end;    (* econst *)
  2138. X
  2139. X    (*    Emit a typedef.                        *)
  2140. X    procedure etypedef;
  2141. X
  2142. X        (*    Workhorse for etypedef, this procedure also    *)
  2143. X        (*    renames all fields in record-unions when    *)
  2144. X        (*    necessary.                    *)
  2145. X        procedure etdef(uid : idptr; tp : treeptr);
  2146. X
  2147. X        var    i    : integer;
  2148. X            tq    : treeptr;
  2149. X
  2150. X            (*    Emit definition for an integer subrange    *)
  2151. X            (*    using data from worddefs set up during    *)
  2152. X            (*    initialization.                *)
  2153. X            procedure etrange(tp : treeptr);
  2154. X
  2155. X            label    999;
  2156. X
  2157. X            var    lo, hi    : integer;
  2158. X                i    : 1 .. maxmachdefs;
  2159. X
  2160. X            begin
  2161. X                lo := clower(tp);
  2162. X                hi := cupper(tp);
  2163. X                (* scan CPU word definitions for a type
  2164. X                   enclosing wanted range *)
  2165. X                for i := 1 to nmachdefs do
  2166. X                    with machdefs[i] do
  2167. X                    if (lo >= lolim) and (hi <= hilim) then
  2168. X                        begin
  2169. X                        (* found it, print type name *)
  2170. X                        printtok(typstr);
  2171. X                        goto 999
  2172. X                        end;
  2173. X                fatal(erange);
  2174. X            999:
  2175. X            end;
  2176. X
  2177. X            (*    Print last component of identifier.    *)
  2178. X            procedure printsuf(ip : idptr);
  2179. X
  2180. X            var    w    : toknbuf;
  2181. X                i, j    : toknidx;
  2182. X
  2183. X            begin
  2184. X                gettokn(ip^.istr, w);
  2185. X                i := 1;
  2186. X                j := i;
  2187. X                while w[i] <> chr(null) do
  2188. X                    begin
  2189. X                    if w[i] = '.' then
  2190. X                        j := i;
  2191. X                    i := i + 1
  2192. X                    end;
  2193. X                if w[j] = '.' then
  2194. X                    j := j + 1;
  2195. X                while w[j] <> chr(null) do
  2196. X                    begin
  2197. X                    write(w[j]);
  2198. X                    j := j + 1
  2199. X                    end
  2200. X            end;
  2201. X
  2202. X        begin    (* etdef *)
  2203. X            case tp^.tt of
  2204. X              nid:
  2205. X                printid(tp^.tsym^.lid);
  2206. X              nptr:
  2207. X                begin
  2208. X                tq := typeof(tp^.tptrid);
  2209. X                if tq^.tt = nrecord then
  2210. X                    begin
  2211. X                    write('struct ');
  2212. X                    printid(tq^.tuid)
  2213. X                    end
  2214. X                else
  2215. X                    printid(tp^.tptrid^.tsym^.lid);
  2216. X                write(' *');
  2217. X                end;
  2218. X              nscalar:
  2219. X                begin
  2220. X                write('enum { ');
  2221. X                increment;
  2222. X                tp := tp^.tscalid;
  2223. X
  2224. X                (* avoid bug in C-compiler:
  2225. X                       enums are mixed in same namespace *)
  2226. X                if tp^.tsym^.lid^.inref > 1 then
  2227. X                    tp^.tsym^.lid :=
  2228. X                        mkrename('E', tp^.tsym^.lid);
  2229. X                printid(tp^.tsym^.lid);
  2230. X                i := 1;
  2231. X                while tp^.tnext <> nil do
  2232. X                    begin
  2233. X                    if i >= 4 then
  2234. X                        begin
  2235. X                        writeln(',');
  2236. X                        indent;
  2237. X                        i := 1
  2238. X                        end
  2239. X                    else begin
  2240. X                        write(', ');
  2241. X                        i := i + 1
  2242. X                         end;
  2243. X                    tp := tp^.tnext;
  2244. X                    if tp^.tsym^.lid^.inref > 1 then
  2245. X                        tp^.tsym^.lid :=
  2246. X                        mkrename('E', tp^.tsym^.lid);
  2247. X                    printid(tp^.tsym^.lid)
  2248. X                    end;
  2249. X                decrement;
  2250. X                write(' } ')
  2251. X                end;
  2252. X              nsubrange:
  2253. X                begin
  2254. X                tq := typeof(tp^.tlo);
  2255. X                if tq = typnods[tinteger] then
  2256. X                    etrange(tp)
  2257. X                else begin
  2258. X                    if tq^.tup^.tt = ntype then
  2259. X                        tq := tq^.tup^.tidl;
  2260. X                    etdef(nil, tq)
  2261. X                     end
  2262. X                end;
  2263. X              nfield:
  2264. X                begin
  2265. X                etdef(nil, tp^.tbind);
  2266. X                write(tab1);
  2267. X                tp := tp^.tidl;
  2268. X                if uid <> nil then
  2269. X                    tp^.tsym^.lid :=
  2270. X                        mkconc('.', uid, tp^.tsym^.lid);
  2271. X                printsuf(tp^.tsym^.lid);
  2272. X                i := 1;
  2273. X                while tp^.tnext <> nil do
  2274. X                    begin
  2275. X                    if i >= 4 then
  2276. X                        begin
  2277. X                        writeln(',');
  2278. X                        indent;
  2279. X                        write(tab1);
  2280. X                        i := 1
  2281. X                        end
  2282. X                    else begin
  2283. X                        write(', ');
  2284. X                        i := i + 1
  2285. X                         end;
  2286. X                    tp := tp^.tnext;
  2287. X                    if uid <> nil then
  2288. X                        tp^.tsym^.lid :=
  2289. X                        mkconc('.', uid, tp^.tsym^.lid);
  2290. X                    printsuf(tp^.tsym^.lid);
  2291. X                    end;
  2292. X                writeln(';');
  2293. X                end;
  2294. X              nrecord:
  2295. X                begin
  2296. X                write('struct ');
  2297. X                if tp^.tuid = nil then
  2298. X                    tp^.tuid := uid
  2299. X                else if uid = nil then
  2300. X                    printid(tp^.tuid);
  2301. X                writeln(' {');
  2302. X                increment;
  2303. X                if (tp^.tflist = nil) and
  2304. X                            (tp^.tvlist = nil) then
  2305. X                    begin
  2306. X                    (* C doesn't allow empty structures *)
  2307. X                    indent;
  2308. X                    writeln(inttyp, tab1, 'dummy;')
  2309. X                    end;
  2310. X                tq := tp^.tflist;
  2311. X                while tq <> nil do
  2312. X                    begin
  2313. X                    indent;
  2314. X                    etdef(uid, tq);
  2315. X                    tq := tq^.tnext
  2316. X                    end;
  2317. X                if tp^.tvlist <> nil then
  2318. X                    begin
  2319. X                    indent;
  2320. X                    writeln('union {');
  2321. X                    increment;
  2322. X                    tq := tp^.tvlist;
  2323. X                    while tq <> nil do
  2324. X                        begin
  2325. X                        if (tq^.tvrnt^.tflist <> nil) or
  2326. X                         (tq^.tvrnt^.tvlist <> nil) then
  2327. X                            begin
  2328. X                            indent;
  2329. X                            if uid = nil then
  2330. X                                etdef(mkvrnt,
  2331. X                                tq^.tvrnt)
  2332. X                            else
  2333. X                                etdef(mkconc('.',
  2334. X                                   uid, mkvrnt),
  2335. X                                tq^.tvrnt);
  2336. X                            writeln(';')
  2337. X                            end;
  2338. X                        tq := tq^.tnext
  2339. X                        end;
  2340. X                    decrement;
  2341. X                    indent;
  2342. X                    writeln('} U;');
  2343. X                    end;
  2344. X                decrement;
  2345. X                indent;
  2346. X                if tp^.tup^.tt = nvariant then
  2347. X                    begin
  2348. X                    write('} ');
  2349. X                    printsuf(tp^.tuid)
  2350. X                    end
  2351. X                else
  2352. X                    write('}');
  2353. X                end;
  2354. X              nconfarr:
  2355. X                begin
  2356. X                write('struct ');
  2357. X                printid(tp^.tcuid);
  2358. X                write(' { ');
  2359. X                etdef(nil, tp^.tcelem);
  2360. X                write(tab1, 'A[]; }')
  2361. X                end;
  2362. X              narray:
  2363. X                begin
  2364. X                write('struct { ');
  2365. X                etdef(nil, tp^.taelem);
  2366. X                write(tab1, 'A[');
  2367. X                tq := typeof(tp^.taindx);
  2368. X                if tq^.tt = nsubrange then
  2369. X                    begin
  2370. X                    if arithexpr(tq^.thi) then
  2371. X                        begin
  2372. X                        eexpr(tq^.thi);
  2373. X                        if cvalof(tq^.tlo) <> 0 then
  2374. X                            begin
  2375. X                            write(' - ');
  2376. X                            eexpr(tq^.tlo)
  2377. X                            end
  2378. X                        end
  2379. X                    else begin
  2380. X                        write('(int)(');
  2381. X                        eexpr(tq^.thi);
  2382. X                        if cvalof(tq^.tlo) <> 0 then
  2383. X                            begin
  2384. X                            write(') - (int)(');
  2385. X                            eexpr(tq^.tlo)
  2386. X                            end;
  2387. X                        write(')')
  2388. X                         end;
  2389. X                    write(' + 1')
  2390. X                    end
  2391. X                else
  2392. X                    write(crange(tp^.taindx):1);
  2393. X                write(']; }')
  2394. X                end;
  2395. X              nfileof:
  2396. X                begin
  2397. X                writeln('struct {');
  2398. X                indent;
  2399. X                writeln(tab1, 'FILE', tab1, '*fp;');
  2400. X                indent;
  2401. X                writeln(tab1, filebits, tab1, 'eoln:1,');
  2402. X                indent;
  2403. X                writeln(tab3, 'eof:1,');
  2404. X                indent;
  2405. X                writeln(tab3, 'out:1,');
  2406. X                indent;
  2407. X                writeln(tab3, 'init:1,');
  2408. X                indent;
  2409. X                writeln(tab3, ':', filefill:1, ';');
  2410. X                indent;
  2411. X                write(tab1);
  2412. X                etdef(nil, tp^.tof);
  2413. X                writeln(tab1, 'buf;');
  2414. X                indent;
  2415. X                write('} ')
  2416. X                end;
  2417. X              nsetof:
  2418. X                write('struct { ', setwtyp, tab1, 'S[',
  2419. X                            csetsize(tp):1, ']; }');
  2420. X              npredef:
  2421. X                begin
  2422. X                case tp^.tobtyp of
  2423. X                  tboolean:
  2424. X                    printid(defnams[dboolean]^.lid);
  2425. X                  tchar:
  2426. X                    write(chartyp);
  2427. X                  tinteger:
  2428. X                    printid(defnams[dinteger]^.lid);
  2429. X                  treal:
  2430. X                    printid(defnams[dreal]^.lid);
  2431. X                  tstring:
  2432. X                    write(chartyp, ' *');
  2433. X                  ttext:
  2434. X                    write('text');
  2435. X                  tnil,
  2436. X                  tset,
  2437. X                  terror:
  2438. X                    fatal(etree);
  2439. X                  tnone:
  2440. X                    write(voidtyp);
  2441. X                end (* case *)
  2442. X                end;
  2443. X              nempty:
  2444. X                write(voidtyp);
  2445. X            end;(* case *)
  2446. X        end;    (* etdef *)
  2447. X    begin
  2448. X        etdef(nil, tp)
  2449. X    end;    (* etypedef *)
  2450. X
  2451. X    (*    Emit code for type declarations.            *)
  2452. X    procedure etype(tp : treeptr);
  2453. X
  2454. X    var    sp    : symptr;
  2455. X
  2456. X    begin
  2457. X        while tp <> nil do
  2458. X            begin
  2459. X            (* if identifier used more than once we rename the type
  2460. X               to avoid typedef'ing an identifier twice *)
  2461. X            sp := tp^.tidl^.tsym;
  2462. X            if sp^.lid^.inref > 1 then
  2463. X                sp^.lid := mkrename('Y', sp^.lid);
  2464. X            indent;
  2465. X            write(typdef);
  2466. X            etypedef(tp^.tbind);
  2467. X            write(tab1);
  2468. X            printid(sp^.lid);
  2469. X            writeln(';');
  2470. X            tp := tp^.tnext
  2471. X            end
  2472. X    end;
  2473. X
  2474. X    (*    Emit code for variable declarations.            *)
  2475. X    procedure evar(tp : treeptr);
  2476. X
  2477. X    label    555;
  2478. X
  2479. X    var    tq    : treeptr;
  2480. X        i    : integer;
  2481. X
  2482. X    begin
  2483. X        while tp <> nil do
  2484. X            begin
  2485. X            indent;
  2486. X            case tp^.tt of
  2487. X              nvar,
  2488. X              nvalpar,
  2489. X              nvarpar:
  2490. X                begin
  2491. X                if tp^.tattr = aregister then
  2492. X                    write(registr);
  2493. X                etypedef(tp^.tbind)
  2494. X                end;
  2495. X              nparproc,
  2496. X              nparfunc:
  2497. X                begin
  2498. X                if tp^.tt = nparproc then
  2499. X                    write(voidtyp)
  2500. X                else
  2501. X                    etypedef(tp^.tpartyp);
  2502. X                tq := tp^.tparid;
  2503. X                write(tab1, '(*');
  2504. X                printid(tq^.tsym^.lid);
  2505. X                write(')()');
  2506. X                goto 555
  2507. X                end
  2508. X            end;(* case *)
  2509. X            write(tab1);
  2510. X            tq := tp^.tidl;
  2511. X            i := 1;
  2512. X            repeat
  2513. X                if tp^.tt = nvarpar then
  2514. X                    write('*');
  2515. X                printid(tq^.tsym^.lid);
  2516. X                tq := tq^.tnext;
  2517. X                if tq <> nil then
  2518. X                    begin
  2519. X                    if i >= 6 then
  2520. X                        begin
  2521. X                        i := 1;
  2522. X                        writeln(',');
  2523. X                        indent;
  2524. X                        write(tab1)
  2525. X                        end
  2526. X                    else begin
  2527. X                        i := i + 1;
  2528. X                        write(', ')
  2529. X                         end
  2530. X
  2531. END_OF_FILE
  2532. if test 50280 -ne `wc -c <'ptc.p.3'`; then
  2533.     echo shar: \"'ptc.p.3'\" unpacked with wrong size!
  2534. fi
  2535. # end of 'ptc.p.3'
  2536. fi
  2537. echo shar: End of archive 9 \(of 12\).
  2538. cp /dev/null ark9isdone
  2539. MISSING=""
  2540. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  2541.     if test ! -f ark${I}isdone ; then
  2542.     MISSING="${MISSING} ${I}"
  2543.     fi
  2544. done
  2545. if test "${MISSING}" = "" ; then
  2546.     echo You have unpacked all 12 archives.
  2547.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2548. else
  2549.     echo You still need to unpack the following archives:
  2550.     echo "        " ${MISSING}
  2551. fi
  2552. ##  End of shell archive.
  2553. exit 0
  2554. -- 
  2555.  
  2556. Rich $alz            "Anger is an energy"
  2557. Cronus Project, BBN Labs    rsalz@bbn.com
  2558. Moderator, comp.sources.unix    sources@uunet.uu.net
  2559.